package com.paranoidmonkey.ode.Joint;

import java.nio.Buffer;

import com.paranoidmonkey.ode.AndrODE;
import com.paranoidmonkey.ode.Body;

public class Joint {
	protected long handle;
	
	//private final static int None=0;
	private final static int Ball=1;
	private final static int Hinge=2;
	private final static int Slider=3;
	private final static int Contact=4;
	private final static int Universal=5;
	private final static int Hinge2=6;
	private final static int Fixed=7;
	private final static int Null=8;
	private final static int AMotor=9;
	private final static int LMotor=10;
	private final static int Plane2D=11;
	private final static int PR=12;
	private final static int PU=13;
	private final static int Piston=14;
		
	
	protected Joint(){
		handle=-1;
	}
	private Joint(long ID){
		handle=ID;
	}

	public boolean isNull(){
		return (handle==0);
	}

	public static Joint Construct(long ID){
		switch(AndrODE.dJointGetType(ID)){
		case Ball:
			return (Ball)new Joint(ID);
		case Hinge:
			return (Hinge)new Joint(ID);
		case Hinge2:
			return (Hinge2)new Joint(ID);
		case Contact:
			return (ContactJoint)new Joint(ID);
		case Fixed:
			return (Fixed)new Joint(ID);
		case Piston:
			return (Piston)new Joint(ID);
		case Plane2D:
			return (Plane2D)new Joint(ID);
		case PR:
			return (PR)new Joint(ID);
		case PU:
			return (PU)new Joint(ID);
		case Universal:
			return (Universal)new Joint(ID);
		case AMotor:
			return (AMotor)new Joint(ID);
		case LMotor:
			return (LMotor)new Joint(ID);
		case Slider:
			return (Slider)new Joint(ID);
		case Null:
			return (Null)new Joint(ID);
		}
		return null;
	}
	
	public void setFixed(){
		AndrODE.dJointSetFixed (handle);
	}

	public void destroy(){
		AndrODE.dJointDestroy (handle);
	}
	public int getNumBodies(){
		return AndrODE.dJointGetNumBodies(handle);
	}
	public void attach(Body body1,Body body2){
		AndrODE.dJointAttach (handle, body1.getHandle(), body2.getHandle());
	}
	public void setEnabled(boolean state){
		if (state){
			AndrODE.dJointEnable (handle);
		}else{
			AndrODE.dJointDisable (handle);
		}
	}
	public boolean isEnabled(){
		return (AndrODE.dJointIsEnabled (handle)!=0);
	}
	public void setData(Buffer data){
		AndrODE.dJointSetData (handle, data);
	}
	public Object getData(){
		return AndrODE.dJointGetData(handle);
	}
	public int getType(){
		return AndrODE.dJointGetType(handle);
	}
	public Body getBody(int index){
		return new Body(AndrODE.dJointGetBody (handle, index));
	}
	public void setFeedback(JointFeedback fb){
		AndrODE.dJointSetFeedback (handle, fb.handle);
	}
	public JointFeedback getFeedback(){
		return new JointFeedback(AndrODE.dJointGetFeedback (handle));
	}
		
	public void connectingJoint(Body body1, Body body2){
		AndrODE.dConnectingJoint (body1.getHandle(), body2.getHandle());
	}
	public int connectingJointList(Body body1, Body body2,long[] joint){
		return AndrODE.dConnectingJointList (body1.getHandle(), body2.getHandle(), joint);
	}
	public void areConnected(Body body1, Body body2){
		AndrODE.dAreConnected (body1.getHandle(), body2.getHandle());
	}
	public void areConnectedExcluding(Body body1, Body body2,int joint_type){
		AndrODE.dAreConnectedExcluding (body1.getHandle(), body2.getHandle(), joint_type);
	}

	public boolean equals(Object b){
		if (b instanceof Joint) {
			if (((Joint)b).handle==handle){
				return true;
			}
		}
		return false;
	}

}
